spring data jpa进阶

您所在的位置:网站首页 spring data jpa和mybatis spring data jpa进阶

spring data jpa进阶

2023-03-21 18:25| 来源: 网络整理| 查看: 265

自定义SQL查询 复杂查询如何实现 关于事务 原理概述

不了解spring data jpa的建议先看我之前的文章

spring data jpa入门示例

本篇的源码地址:

https://github.com/pony-maggie/spring-boot-jpa-advance

自定义SQL查询

mybatis擅长大量自定义查询的场景,spring data jpa虽然优势不在这里,但是也支持自定义SQL查询。它主要是通过@Query注解支持的。

12345678@Transactional @Modifying @Query("update Student u set u.name = ?1 where u.id = ?2") int modifyNameById(String name, Long id); @Query("select u from Student u where u.age = ?1") Student findByMyAge(int age);

@Query 注解中编写更新类语句, 但必须使用 @Modifying 进行修饰. 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作

@Transactional表示开启事务,如果不加的话会下面的异常:

1javax.persistence.TransactionRequiredException

然后我们在controller里加入测试接口进行测试。

http://localhost:8080/student/byAge?age=16

http://localhost:8080/student/modifyNameById?name=zhangsan&id=3

复杂查询如何实现

有些业务场景下我们需要复杂一些的查询,比如指定某些条件进行分页,关联查询等。spring data jpa给我们提供了JpaSpecificationExecutor用来支持这样的场景。

JpaSpecificationExecutor提供了以下接口

123456789101112public interface JpaSpecificationExecutor { T findOne(Specification spec); List findAll(Specification spec); Page findAll(Specification spec, Pageable pageable); List findAll(Specification spec, Sort sort); long count(Specification spec); }

传进去的参数Specification是个接口,我们主要的工作就是实现这个接口。我这里实现了一个:

1234567891011public class MyTestSpec implements Specification { @Override public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { Path id = root.get("id"); Predicate predicate = criteriaBuilder.gt(id, 3); return predicate; } }

然后我们在service里调用测试下,

12345678//指定条件分页查询,参数分别是页数和每页的大小 public Page findByMySpec(int page, int pageSize){ Sort sort = new Sort(Sort.Direction.DESC, "id"); Pageable pageable = PageRequest.of(page, pageSize); Page students = studentRepository.findAll(new MyTestSpec(), pageable); return students; }

打印的SQL如下:

12Hibernate: select student0_.t_id as t_id1_0_, student0_.t_age as t_age2_0_, student0_.t_name as t_name3_0_, student0_.t_school as t_school4_0_ from t_student student0_ where student0_.t_id>3 limit ?, ? Hibernate: select count(student0_.t_id) as col_0_0_ from t_student student0_ where student0_.t_id>3

可以看出我们通过自定义Specification实现了一个id大于3的分页查询操作。所以利用Specification我们可以自定义各种复杂的查询,甚至可以把各种复杂的查询组合起来使用。

大家可以下载源码自己测试看看效果。

关于事务

JpaRepository提供的增删改查接口方法默认都是支持事务的,我们不需要再单独声明。这是因为JpaRepository都有一个默认实现SimpleJpaRespositry,它的定义如下:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152@Repository @Transactional(readOnly = true) public class SimpleJpaRepository implements JpaRepository, JpaSpecificationExecutor { ...... @Transactional public void delete(ID id) { ...... } @Transactional public void delete(T entity) { ...... } @Transactional public void delete(Iterable


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3